package com.shadowtorcher.TableRolePlayingSystem.controller;


import com.shadowtorcher.TableRolePlayingSystem.bean.User;
import com.shadowtorcher.TableRolePlayingSystem.controller.WebSocket.SaveProcessor;
import com.shadowtorcher.TableRolePlayingSystem.dao.UserDao;
import com.shadowtorcher.TableRolePlayingSystem.util.Security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.crypto.Cipher;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.concurrent.ThreadLocalRandom;

@Controller

@RequestMapping("love")
public class UserController {
    @Autowired
    private UserDao dao;

    // 这里是注册
    // password 经过服务器公钥加密后的密码字符串
    // publicKey 是浏览器生成的公钥
    @RequestMapping("createUserData")
    public void createUserData(@RequestParam("password") String password, @RequestParam("userName") String userName,
                               @RequestParam("userData") String userData, @RequestParam("publicKey") String publicKey,
                               HttpServletResponse response) throws IOException {
        if (dao.findUserByName(userName) != null) {
            PrintWriter out = response.getWriter();
            out.print("USERNAME_ALREADY_IN_USE");
            return;
        }
        try {
            Cipher cipher = Security.getServerDecodeCipher();
            String realPassword = new String(cipher.doFinal(Base64.getDecoder().decode(password)));
            SaveProcessor.registerNewUser(userName, encryption(realPassword), userData, publicKey);
            response.getWriter().write("SUCCESS");
        } catch (Exception e) {
            PrintWriter out = response.getWriter();
            out.print("RAS_CHIPHER_ERROR");
            e.printStackTrace();
        }
    }

    // 这里是创建一个 PM 帐号和对映的地图
    @RequestMapping("createDM")
    public void createDM(@RequestParam("password") String password, @RequestParam("userName") String userName,
                         @RequestParam("roomName") String roomName, @RequestParam("publicKey") String publicKey,
                         HttpServletResponse response) throws IOException {
        if (dao.findUserByName(userName) != null) {
            PrintWriter out = response.getWriter();
            out.print("USERNAME_ALREADY_IN_USE");
            return;
        }
        if(SaveProcessor.getMapByMapID(roomName) != null){
            PrintWriter out = response.getWriter();
            out.print("ROOMNAME_ALREADY_IN_USE");
            return;
        }
        try {
            Cipher cipher = Security.getServerDecodeCipher();
            String realPassword = new String(cipher.doFinal(Base64.getDecoder().decode(password)));
            SaveProcessor.registerNewUser(userName, encryption(realPassword), "{}", publicKey);
            SaveProcessor.createMap(roomName, userName);
            response.getWriter().write("SUCCESS");
        } catch (Exception e) {
            PrintWriter out = response.getWriter();
            out.print("RAS_CHIPHER_ERROR");
            e.printStackTrace();
        }
    }

    // 这里是登录
    // name 是用户名
    // password 是在前面加上随机字符串的加密密码
    @RequestMapping("userLogin")
    public void userLogin(@RequestParam("name") String name, @RequestParam("password") String password,
                          @RequestParam("publicKey") String publicKey, HttpServletResponse response,
                          HttpSession session) throws IOException {
        String random = (String) session.getAttribute("random");
        session.removeAttribute("random"); // 随机数用过一次不能再用第二次
        if (random == null) {
            response.getWriter().write("RANDOM_NOT_INIT");
            return;
        }
        try {
            Cipher cipher = Security.getServerDecodeCipher();
            String realPassword = new String(cipher.doFinal(Base64.getDecoder().decode(password)));
            if (!realPassword.startsWith(random)) {
                response.getWriter().write("RANDOM_INCORRECT");
                return;
            }
            realPassword = realPassword.substring(random.length());
            realPassword = encryption(realPassword);
            User user = SaveProcessor.getUserByUserPassword(name, realPassword);
            if (user != null) {
                SaveProcessor.upDateUserPublicKey(name, publicKey);
                response.getWriter().write("SUCCESS");
            } else {
                response.getWriter().write("INCORRECT_NAME_OR_PASSWORD");
            }
        } catch (Exception e) {
            PrintWriter out = response.getWriter();
            out.print("RAS_CHIPHER_ERROR");
        }
    }

    @RequestMapping("getRandom")
    public void getRandom(HttpSession session, HttpServletResponse response) throws IOException {
        StringBuilder builder = new StringBuilder(20);
        for (int i = 0; i < 20; i++) {
            builder.append((char) (ThreadLocalRandom.current().nextInt(33, 128)));
        }
        String rand = builder.toString();
        response.getWriter().write(rand);
        session.setAttribute("random", rand);
    }

    protected String encryption(String password) {
        try {
            password += "这是一些无意义的字符";
            password = Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-1").digest(password.getBytes()));
            return password;
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }
}
